-
Notifications
You must be signed in to change notification settings - Fork 114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[A2-815] list rules with staged and current rules #646
[A2-815] list rules with staged and current rules #646
Conversation
eda06f7
to
b617f66
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some reviewer notes inline
@@ -111,6 +111,8 @@ message ProjectRule { | |||
string name = 3; | |||
ProjectRuleTypes type = 4; | |||
repeated Condition conditions = 5; | |||
bool deleted = 6; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ℹ️Surfacing the deleted and staged/applied status of a rule in the interservice API. Nothing done for automate-gateway
yet.
@@ -173,7 +175,9 @@ message GetRuleResp { | |||
ProjectRule rule = 1; | |||
} | |||
|
|||
message ListRulesReq {} | |||
message ListRulesReq { | |||
bool include_staged = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ℹ️ Pass ListRulesReq{IncludeStaged: true}
to also see staged rules.
@@ -111,6 +111,8 @@ message ProjectRule { | |||
string name = 3; | |||
ProjectRuleTypes type = 4; | |||
repeated Condition conditions = 5; | |||
bool deleted = 6; | |||
string status = 7; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OMG why no enum?!!!
I hear you -- but it's just so annoying to convert three different kinds of enums (storage layer, authz-service GRPC, automate-gateway GRPC), and I'm not convinced it's worth it. Happy to listen to arguments, but maybe we can just make our lives a little brighter and our PRs a little smaller. 😉
Also, in the external API (automate-gateway), we can (and should) still use an enum.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like the compromise of having an enum at the gateway and not in the domain layer. The enum unwrapping code is super super annoying.
@@ -143,6 +143,7 @@ func TestCreateRule(t *testing.T) { | |||
Operator: api.ProjectRuleConditionOperators_MEMBER_OF, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ℹ️I haven't added any tests on that layer yet.
@@ -0,0 +1,154 @@ | |||
BEGIN; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ℹ️ Updated SQL functions to return the "status" = "applied"/"staged".
Converted to use json_build_object
in the process.
@@ -137,7 +137,7 @@ SELECT array_agg(policy_id) FROM pol_ids`, | |||
func (p *pg) ListPolicies(ctx context.Context) ([]*v2.Policy, error) { | |||
projectsFilter, err := projectsListFromContext(ctx) | |||
if err != nil { | |||
return nil, p.processError(err) | |||
return nil, err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one of two drive-by cleanups, please see the commit
} | ||
|
||
ctx, cancel := context.WithCancel(ctx) | ||
defer cancel() | ||
|
||
tx, err := p.db.BeginTx(ctx, nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one of two drive-by cleanups, please see the commit
return p.listRulesUsingFunction(ctx, "SELECT query_rules($1)") | ||
} | ||
|
||
func (p *pg) ListStagedAndAppliedRules(ctx context.Context) ([]*v2.Rule, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ℹ️ new method for retrieving rules of each state -- as mentioned in A2-815.
db.Flush(t) | ||
} | ||
} | ||
func TestListStagedAndAppliedRules(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The amount of copy-paste involved in creating these tests is deeply unsatisfying :grumpycat:
} | ||
|
||
func insertStagedRule(t *testing.T, db *testhelpers.TestDB, rule storage.Rule) { | ||
func insertStagedRule(t *testing.T, db *testhelpers.TestDB, rule *storage.Rule) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ℹ️ We have to change the function type to pass a pointer to mutate the rule
argument, to add the status below
BEGIN; | ||
|
||
CREATE OR REPLACE FUNCTION | ||
query_staged_and_applied_rules(_project_filter TEXT[]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this query concatenate the rows from the two tables?
for GetStagedOrAppliedRule(id)
we return the staged rule if it exists, otherwise return the applied rule (due to an acceptance requirement that users should always see the latest staged change). we may want to make this query work the same way - returning only one version of each rule.
although since i don't know of a specific case where we're using this query yet, this is probably ok for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple points.
- Looking at
GetStagedOrAppliedRule
I do not believe it does what you think, @bcmdarroch . Looks like the SQL underlying that call,query_staged_rule
, works exactly the same as this new function, returning both staged and applied rules. - I do take issue with the name of this new function
query_staged_and_applied_rules
compared to the aforementioned functionquery_staged_rule
. Please rename one or the other so they differ only in plurality. 😁
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we've resolved that in standup:
returning both staged and applied rules.
but we use QueryRowContext
, so we're basically returning the staged one first (if it exists), so we're OK here, even if by accident. There might be a cleaner solution, but this one will do. 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
query_staged_rules
checks both applied
and staged
but only returns the applied rule if no staged version exists.
@@ -243,6 +243,7 @@ func (s *State) GetPolicyChangeNotifier(ctx context.Context) (v2.PolicyChangeNot | |||
} | |||
|
|||
func (s *State) CreateRule(_ context.Context, rule *storage.Rule) (*storage.Rule, error) { | |||
rule.Status = "applied" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we want to match postgres behavior, the status here would be staged
. only on ApplyRule does everything staged get set to applied
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaving this as-is to not break all the memstore-based tests. Let's nuke them. 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally looks good to me. I find it a bit strange that we don't just have separate APIs for some of the staged vs applied stuff but that's the general shape we've taken so far so might as well see it through and refactor as needed in the future.
@@ -111,6 +111,8 @@ message ProjectRule { | |||
string name = 3; | |||
ProjectRuleTypes type = 4; | |||
repeated Condition conditions = 5; | |||
bool deleted = 6; | |||
string status = 7; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like the compromise of having an enum at the gateway and not in the domain layer. The enum unwrapping code is super super annoying.
@@ -470,6 +471,7 @@ func TestGetRule(t *testing.T) { | |||
Type: api.ProjectRuleTypes_NODE, | |||
ProjectId: projectID, | |||
Conditions: apiConditions, | |||
Status: "applied", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this could be a constant? We have some at the DB level after the DeleteRule
refactor PR merged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah a constant in a different package 😉 this is only tests I'll add another package-level one.
@@ -243,6 +243,7 @@ func (s *State) GetPolicyChangeNotifier(ctx context.Context) (v2.PolicyChangeNot | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heh probably not as much WIP as we should. Left a comment in Slack.
BEGIN; | ||
|
||
CREATE OR REPLACE FUNCTION | ||
query_staged_and_applied_rules(_project_filter TEXT[]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple points.
- Looking at
GetStagedOrAppliedRule
I do not believe it does what you think, @bcmdarroch . Looks like the SQL underlying that call,query_staged_rule
, works exactly the same as this new function, returning both staged and applied rules. - I do take issue with the name of this new function
query_staged_and_applied_rules
compared to the aforementioned functionquery_staged_rule
. Please rename one or the other so they differ only in plurality. 😁
'name', r.name, | ||
'type', r.type, | ||
'deleted', r.deleted, | ||
'status', 'staged', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider SQL constants for 'staged' and 'applied'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really? As far as I understand it, constants in SQL are scoped per-function. So, this functions could have a constant, but there's not much to gain, really, since both strings only occurr once.... Also it doesn't look common in our code base to have SQL constants. 😃
b617f66
to
500d2a3
Compare
rebased. will adress review comments later. |
500d2a3
to
72969e2
Compare
…ed to PG Signed-off-by: Stephan Renatus <[email protected]>
If these methods _had_ multiple SQL calls, using a transaction, properly threaded in, would be reasonable. However right now, they both only execute one query, so I've cleaned these up. > Read Committed is the default isolation level in PostgreSQL. When a > transaction uses this isolation level, a SELECT query (without a FOR > UPDATE/SHARE clause) sees only data committed before the query began; it > never sees either uncommitted data or changes committed during query > execution by concurrent transactions. In effect, a SELECT query sees a > snapshot of the database as of the instant the query begins to run. See https://www.postgresql.org/docs/9.1/transaction-iso.html Signed-off-by: Stephan Renatus <[email protected]>
Signed-off-by: Stephan Renatus <[email protected]>
Signed-off-by: Stephan Renatus <[email protected]>
Signed-off-by: Stephan Renatus <[email protected]>
Signed-off-by: Stephan Renatus <[email protected]>
Signed-off-by: Stephan Renatus <[email protected]>
Signed-off-by: Stephan Renatus <[email protected]>
Signed-off-by: Blake Johnson <[email protected]>
cfe939d
to
b97fd6e
Compare
🔩 Description
This adds a
ListStagedAndAppliedRules
to the storage layer, and another grpc method to authz-service exposing it.TODO:
👍 Definition of Done
😉
👟 Demo Script / Repro Steps
rebuild components/authz-service
TODO
⛓️ Related Resources
✅ Checklist